package com.by.zhdoctor.web.rest;

import app.cloud.client.axis2.Client;
import app.cloud.client.utils.HdfsOperator;
import app.cloud.common.Target;
import com.by.zhdoctor.config.Constants;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import sun.net.www.protocol.http.HttpURLConnection;

import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;


/**
 * Created by Abe on 2017-05-22.
 * 每一个小时执行一次Token获取，Token获取成功执行消息记录下载
 */
@Async
@Component
public class MessageTasks {

    private final Logger log = LoggerFactory.getLogger(MessageTasks.class);

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH");

    private  String url="http://a1.easemob.com/1169170110115984/zh-doctor/chatmessages/";

    private static final String Url = "https://a1.easemob.com/1169170110115984/zh-doctor/token";

    private static  String HxDate;

    private Gson gson = new GsonBuilder().create();

    private JsonObject jsonObject=null;

    private  JSONObject res = null;


    /**
     * 消息记录文件请求
     *
     */
    public void get() throws KeyStoreException, KeyManagementException, IOException {
        Calendar date2 = Calendar.getInstance ();
        date2.add(Calendar.HOUR_OF_DAY,-2);
        HxDate=dateFormat.format(date2.getTime());
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httget = new HttpGet(url+HxDate);
            httget.setHeader("Authorization","Bearer "+ Constants.TOKEN);
            httget.setHeader("Content-Type","application/json");
            CloseableHttpResponse response=httpclient.execute(httget);

                if(response.getStatusLine().getStatusCode() == HttpStatus.OK.value()){
                    //下载消息记录文件
                    downloadNet(response,HxDate);
                }else if(response.getStatusLine().getStatusCode() == HttpStatus.NOT_FOUND.value()){
                    System.out.println("时间："+HxDate+" **************没有消息记录，取消执行下载消息记录文件操作***************************---->");
                }else{
                    System.out.println("获取"+HxDate+"消息记录文件错误："+response.getStatusLine());
                }
        }finally {
            httpclient.close();
        }
    }

    @Scheduled(fixedRate = 1000 * 60 * 60 * 1)
    public void gettoken() throws KeyStoreException, KeyManagementException, IOException {
        Map<String, String> m = new HashMap();
        m.put("grant_type","client_credentials");
        m.put("client_secret","YXA6IZ1jdlMMDXxEjQfOPsx8C7sRTYA");
        m.put("client_id","YXA6LXynMNcjEea7FRPDQzFhIg");
        JSONObject o = new JSONObject(m);

        try {
            res = post(Url,o, false);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        try {
            if(res==null){
                System.out.println(" ****************************Request  Token Failed****************************");
            }else{
                Constants.TOKEN = (String) res.get("access_token");
                System.out.println(" ****************************  Request Token Successfully --开始下载消息记录文件; ");
                get();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Token请求
     *
     */
    public static JSONObject post(String url,JSONObject jsonObject, Boolean header) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
        CloseableHttpClient httpsClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        if (header!=null){
            httpPost.setHeader("Authorization","Bearer "+Constants.TOKEN);
        }
        JSONObject response = null;
        try {
            StringEntity s = new StringEntity(jsonObject.toString());
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            httpPost.setEntity(s);
            HttpResponse res = httpsClient.execute(httpPost);
            if(res.getStatusLine().getStatusCode() == HttpStatus.OK.value()){
                HttpEntity entity = res.getEntity();
                response = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(),"UTF-8")));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            httpsClient.close();
        }
        return response;
    }

    public void downloadNet(CloseableHttpResponse response,String date) throws IOException {

        HttpEntity entity=response.getEntity();
        ContentType contentType = ContentType.getOrDefault(entity);
        Charset charset = contentType.getCharset();
        //reader 是InputStreamReader的抽象类
        Reader reader = new InputStreamReader(entity.getContent(), charset);
        jsonObject=gson.fromJson(reader,JsonObject.class);
        downLoadFromUrl(jsonObject.get("data").getAsJsonArray().get(0).getAsJsonObject().get("url").toString(),date);
    }

    /**
     * 从网络Url中下载文件
     * @param urlStr
     * @param fileName
     * @throws IOException
     */
    public static void  downLoadFromUrl(String urlStr,String fileName) throws IOException{
        urlStr= urlStr. replace("\"","");
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        //设置超时间为3秒
        conn.setConnectTimeout(3*1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);

        //文件保存位置
        File saveDir = new File(Constants.Savepath);
        if(!saveDir.exists()){
            saveDir.mkdir();
        }
        File file = new File(saveDir+File.separator+fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if(fos!=null){
            fos.close();
        }
        if(inputStream!=null){
            inputStream.close();
            System.out.println("*****************************************Message File Download Successfully---->开始上传消息记录文件到HDFS");
            upMessageFile();
        }


        System.out.println("info:"+url+" download success");

    }
    /**
     * 从输入流中获取字节数组
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static  byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     *将文件上传到hdfs
     *
     */
    public static void upMessageFile(){
        Client client=new Client();
        client.userLogin(Constants.LOGIN,Constants.PW);
        Target target=client.getUploadLink(Constants.UPFILEURL);
        System.out.println(target.getMessage());
        //删除文件
        //System.out.println(client.remove("/aaaa/a1/my/2017052411"));
        String url=target.getUrl();
        HdfsOperator hdfsOperator=new HdfsOperator();
        hdfsOperator.init(url);
        System.out.println(hdfsOperator.isInited());
        boolean upflag=hdfsOperator.upload(MessageTasks.class.getResource(Constants.Savepath+HxDate).getFile(),url);
        if(upflag){
            System.out.println("上传消息文件成功");
        }else{
            System.out.println("上传消息文件失败");
        }

    }

    /**
     *   创建新的用户组和用户，并创建用户的文件夹。
     *
     */
    public  static  void createuser(){
        //root登陆
        Client client = new Client();
        client.userLogin("admin", "123456");
        //  创建用户组            创建用户组名称 用户组管理者  密码    用户组在hdfs的根目录--也就是文件夹   备注信息
        client.createTeam(Constants.TEAMNAME, Constants.TEAMMANAGER, Constants.PW, Constants.TEAMNAME, "正和医生");
        client.userLogout();
        //使用用户组管理者登陆创建用户组的用户
        client.teamLogin( Constants.TEAMMANAGER, Constants.PW);
        //最后属性为按用户创建它的目录
        client.createTeamMember(Constants.LOGIN, Constants.PW, Constants.LOGIN, true, true, Constants.LOGIN);
        client.teamLogout();
        client.userLogin("admin", Constants.PW);
        //创建zhdoctor01的文件夹message-history
        System.out.println(client.mkdir(Constants.UPFILEURL).getMessage());
        client.userLogout();
    }
    /**
    *获取密文
    *
     */
//    public static  void getscret(){
//        Client client=new Client();
//        client.userLogin("a1", "123456");
//        Target target=client.getPlayLink("/aaaa/a1/my/xszr.mp4");
//        System.out.println(target.getMessage());
//        String purl=target.getUrl();
//        System.out.println("密文地址：");
//        System.out.println(purl);
//    }
}
